package com.application.magazine;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.FloatMath;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ViewFlipper;

import com.roscopeco.ormdroid.Entity;

@SuppressWarnings("deprecation")
public class MagazineBookRead extends Activity{
	private Button backButton;
	private ImageView imageView1;
//	private FlipViewController flipView;
	private int id =0;
	private int page = 0;
	private boolean isbookmark = false;
	private List<Images> imgList;
	static final int MIN_DISTANCE = 100;
	private ViewFlipper myViewFlipper;
	private float initialXPoint;
	
	private static final float MIN_ZOOM = 1f,MAX_ZOOM = 1f;

    // These matrices will be used to scale points of the image
    Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();

    // The 3 states (events) which the user is trying to perform
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    int mode = NONE;

    // these PointF objects are used to record the point(s) the user is touching
    PointF start = new PointF();
    PointF mid = new PointF();
    float oldDist = 1f;
    private static final String TAG = "Touch";
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		LinearLayout llay=new LinearLayout(this);
//		flipView = new FlipViewController(this, FlipViewController.HORIZONTAL);
//		flipView.setAdapter(new BookFlipAdapter(this));
		
		LayoutInflater controlInflater = LayoutInflater.from(getBaseContext());
		final View topBar = controlInflater.inflate(R.layout.topbarflip, null);
		final View slide = controlInflater.inflate(R.layout.slidview, null);
		
		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, 70);
		RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
		this.addContentView(slide, params2);
		this.addContentView(topBar, params);
		
//		topBar.setVisibility(topBar.GONE);
		System.gc();
		myViewFlipper = (ViewFlipper) findViewById(R.id.myflipper);
		
		 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		 id = preferences.getInt("mag_id",0);
		 page = preferences.getInt("page",0);
		 isbookmark =  preferences.getBoolean("bookmark", false);
		 Magazine mag = Entity.query(Magazine.class).where("id").eq(id).execute();	
		 imgList =  mag.images();
	
		if(imgList != null && imgList.size()>0){
			for(int i=0 ; i<imgList.size(); i++){
			 ImageView imageView = new ImageView(MagazineBookRead.this);
	            String filePath = imgList.get(i).path;
	            File file = new File(filePath);
	    		BitmapFactory.Options options = new BitmapFactory.Options();
	    		options.inTempStorage = new byte[24*1024];
	    		Bitmap bitmapImage = decodeImage(file);
	            imageView.setImageBitmap(bitmapImage);
	            myViewFlipper.addView(imageView);
	          
			}
		}
		
		backButton = (Button) findViewById(R.id.backButt);
		backButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent i = new Intent(MagazineBookRead.this, MainActivity.class);
				startActivity(i);
				finish();
			}
		});
		
		imageView1 = (ImageView) findViewById(R.id.contentNewsImage);
		imageView1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				imageView1.setImageDrawable(getResources().getDrawable(R.drawable.bookmark_selected));
				
				Bookmarks bm = new Bookmarks();
				Images img =  imgList.get(myViewFlipper.getDisplayedChild());
				if(!bm.checkDuplicate(img.path)){
				bm.magazine = img.magazine;
				bm.path = img.path;
				bm.id = bm.getPk();
				bm.page = String.valueOf(myViewFlipper.getDisplayedChild());
				bm.save();
				}else{
					imageView1.setImageDrawable(getResources().getDrawable(R.drawable.bookmark_white));
					
				}
			}
		});
		
		final Gallery gal = (Gallery) findViewById(R.id.pageGallery);
		gal.setSpacing(1);
		gal.setAdapter(new ImageAdapter(this));
		gal.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//               flipView.setSelection(position);
            	myViewFlipper.setDisplayedChild(position);
            }
        });
		
		if(isbookmark){
			myViewFlipper.setDisplayedChild(page);
			gal.setSelection(page);
		}
	
		myViewFlipper.setOnTouchListener(new OnTouchListener() {
			@Override
		    public boolean onTouch(View v, MotionEvent event) 
		    {
		        ImageView view = (ImageView) myViewFlipper.getChildAt(myViewFlipper.getDisplayedChild());
		        view.setScaleType(ImageView.ScaleType.MATRIX);
		        float scale;

		        dumpEvent(event);
		        // Handle touch events here...

		        switch (event.getAction() & MotionEvent.ACTION_MASK) 
		        {
		            case MotionEvent.ACTION_DOWN:   // first finger down only
		            	 								initialXPoint = event.getX();
		                                                savedMatrix.set(matrix);
		                                                start.set(event.getX(), event.getY());
		                                                Log.d(TAG, "mode=DRAG"); // write to LogCat
		                                                mode = DRAG;
		                                                break;

		            case MotionEvent.ACTION_UP: // first finger lifted
		            	if (mode == DRAG) 
                        { 
		            		float finalx = event.getX();
		            		 
		            		if (start.x > finalx && start.x-finalx > 400) {
		            			 Log.d(TAG, "mode=DRAG------"+(start.x-finalx));
		            			if (myViewFlipper.getDisplayedChild() == imgList.size())
		            				break;
		            			myViewFlipper.showNext();
		            			gal.setSelection(myViewFlipper.getDisplayedChild());
		            		} else if(start.x <finalx  && finalx-start.x > 400 ) {
		            			 Log.d(TAG, "mode=DRAG------"+(finalx-initialXPoint));
		            			if (myViewFlipper.getDisplayedChild() == 0)
		            				break;
		            			myViewFlipper.showPrevious();
		            			gal.setSelection(myViewFlipper.getDisplayedChild());
		            		}
                        }
		    	        break;
		            case MotionEvent.ACTION_POINTER_UP: // second finger lifted

		                                                mode = NONE;
		                                                Log.d(TAG, "mode=NONE");
		                                                break;

		            case MotionEvent.ACTION_POINTER_DOWN: // first and second finger down

		                                                oldDist = spacing(event);
		                                                Log.d(TAG, "oldDist=" + oldDist);
		                                                if (oldDist > 5f) {
		                                                    savedMatrix.set(matrix);
		                                                    midPoint(mid, event);
		                                                    mode = ZOOM;
		                                                    Log.d(TAG, "mode=ZOOM");
		                                                }
		                                                break;

		            case MotionEvent.ACTION_MOVE:

		                                                if (mode == DRAG) 
		                                                { 
		                                                    matrix.set(savedMatrix);
		                                                    matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); // create the transformation in the matrix  of points
		                                                } 
		                                                else if (mode == ZOOM) 
		                                                { 
		                                                    // pinch zooming
		                                                    float newDist = spacing(event);
		                                                    Log.d(TAG, "newDist=" + newDist);
		                                                    if (newDist > 5f) 
		                                                    {
		                                                        matrix.set(savedMatrix);
		                                                        scale = newDist / oldDist; // setting the scaling of the
		                                                                                    // matrix...if scale > 1 means
		                                                                                    // zoom in...if scale < 1 means
		                                                                                    // zoom out
		                                                        matrix.postScale(scale, scale, mid.x, mid.y);
		                                                    }
		                                                }
		                                                break;
		        }

		        view.setImageMatrix(matrix); // display the transformation on screen

		        return true; // indicate event was handled
		    }

			
		
		});
		
	}
	
//	
//	@Override
//	public boolean onTouchEvent(MotionEvent event) {
//		switch (event.getAction()) {
//	    case MotionEvent.ACTION_DOWN:
//	        initialXPoint = event.getX();
//	        break;
//	    case MotionEvent.ACTION_UP:
//	        float finalx = event.getX();
//	        if (initialXPoint > finalx) {
//	            if (myViewFlipper.getDisplayedChild() == imgList.size())
//	                break;
//	            myViewFlipper.showNext();
//	        } else {
//	            if (myViewFlipper.getDisplayedChild() == 0)
//	                break;
//	            myViewFlipper.showPrevious();
//	        }
//	        break;
//	    }
//	    return false;
//	    
//	}
	private void midPoint(PointF point, MotionEvent event) 
    {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }
	private float spacing(MotionEvent event) 
    {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

	@Override
	protected void onResume() {
		super.onResume();
//		flipView.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();
//		flipView.onPause();
	}
	 @Override
	 public void onBackPressed() {
		 // Do Here what ever you want do on back press;
	 }

	 public class ImageAdapter extends BaseAdapter {
	        private Context mContext;
			
	        
	        public ImageAdapter(Context c) {
	            mContext = c;
	            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
		 		id = preferences.getInt("mag_id",0);
		 		page = preferences.getInt("page",0);
		 		isbookmark =  preferences.getBoolean("bookmark", false);
		 		Magazine mag = Entity.query(Magazine.class).where("id").eq(id).execute();	
		 		imgList =  mag.images();
	        }

	        public int getCount() {
	            return imgList.size();
	        }

	        public Object getItem(int position) {
	            return position;
	        }

	        public long getItemId(int position) {
	            return position;
	        }

			public View getView(int arg0, View arg1, ViewGroup arg2) {
				// TODO Auto-generated method stub
	            ImageView i = new ImageView(mContext);
	            String filePath = imgList.get(arg0).path;
	            File file = new File(filePath);
	    		BitmapFactory.Options options = new BitmapFactory.Options();
	    		options.inTempStorage = new byte[24*1024];

	    		Bitmap bitmapImage = decodeFile(file);
	    		
	            i.setImageBitmap(bitmapImage);
	            i.setLayoutParams(new Gallery.LayoutParams(80, 80));
	            i.setScaleType(ImageView.ScaleType.FIT_XY);

	            return i;
			}
	    }
	 
	 private Bitmap decodeFile(File f){
		    try {
		        //Decode image size
		        BitmapFactory.Options o = new BitmapFactory.Options();
		        o.inJustDecodeBounds = true;
		        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

		        //The new size we want to scale to
		        final int REQUIRED_SIZE=30;

		        //Find the correct scale value. It should be the power of 2.
		        int scale=1;
		        while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
		            scale*=2;

		        //Decode with inSampleSize
		        BitmapFactory.Options o2 = new BitmapFactory.Options();
		        o2.inSampleSize=scale;
		        Bitmap bitmap =  BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
		       
		        return bitmap;
		    } catch (FileNotFoundException e) {
		    	e.printStackTrace();
		    }
		    return null;
		}
	 private Bitmap decodeImage(File f){
		    try {
		        //Decode image size
		        BitmapFactory.Options o = new BitmapFactory.Options();
		        o.inJustDecodeBounds = true;
		        FileInputStream fis = new FileInputStream(f);
		        BitmapFactory.decodeStream(fis,null,o);
		        fis.close();

		        //The new size we want to scale to
		        final int REQUIRED_SIZE=700;

		        //Find the correct scale value. It should be the power of 2.
		        int scale=1;
		        if (o.outHeight > REQUIRED_SIZE || o.outWidth > REQUIRED_SIZE) {
		            scale = (int)Math.pow(2, (int) Math.round(Math.log(REQUIRED_SIZE / 
		               (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
		        }

		        //Decode with inSampleSize
		        BitmapFactory.Options o2 = new BitmapFactory.Options();
		        o2.inSampleSize = scale;
		        o2.inPurgeable=true;
		        o2.inInputShareable=true;
		        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
		    } catch (Exception e) {
		    	e.printStackTrace();
		    }
		    return null;
		}

	 private void dumpEvent(MotionEvent event) 
	    {
	        String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE","POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
	        StringBuilder sb = new StringBuilder();
	        int action = event.getAction();
	        int actionCode = action & MotionEvent.ACTION_MASK;
	        sb.append("event ACTION_").append(names[actionCode]);

	        if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) 
	        {
	            sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
	            sb.append(")");
	        }

	        sb.append("[");
	        for (int i = 0; i < event.getPointerCount(); i++) 
	        {
	            sb.append("#").append(i);
	            sb.append("(pid ").append(event.getPointerId(i));
	            sb.append(")=").append((int) event.getX(i));
	            sb.append(",").append((int) event.getY(i));
	            if (i + 1 < event.getPointerCount())
	                sb.append(";");
	        }

	        sb.append("]");
	      
	    }

	 
	
}
